home *** CD-ROM | disk | FTP | other *** search
/ Qoole for Quake / Qoole for Quake (USA) / Qoole for Quake (USA).bin / Tutorial / HTML / QUBE.ZIP / SRC / WRITEBSP.C < prev   
Encoding:
C/C++ Source or Header  |  1996-11-05  |  9.9 KB  |  513 lines

  1.  
  2. #include "bsp5.h"
  3.  
  4.  
  5. int        headclipnode;
  6. int        firstface;
  7.  
  8. /*=========================================================================== */
  9.  
  10. /*
  11. ==================
  12. FindFinalPlane
  13.  
  14. Used to find plane index numbers for clip nodes read from child processes
  15. ==================
  16. */
  17. int FindFinalPlane (dplane_t *p)
  18. {
  19.     int        i;
  20.     dplane_t    *dplane;
  21.     
  22.     for (i=0, dplane = dplanes ; i<numplanes ; i++, dplane++)
  23.     {
  24.         if (p->type != dplane->type)
  25.             continue;
  26.         if (p->dist != dplane->dist)
  27.             continue;
  28.         if (p->normal[0] != dplane->normal[0])
  29.             continue;
  30.         if (p->normal[1] != dplane->normal[1])
  31.             continue;
  32.         if (p->normal[2] != dplane->normal[2])
  33.             continue;
  34.         return i;
  35.     }
  36.     
  37. /* */
  38. /* new plane */
  39. /* */
  40.     if (numplanes == MAX_MAP_PLANES)
  41.         Error ("numplanes == MAX_MAP_PLANES");
  42.     dplane = &dplanes[numplanes];
  43.     *dplane = *p;
  44.     numplanes++;
  45.     
  46.     return numplanes - 1;
  47. }
  48.  
  49.  
  50.  
  51. int        planemapping[MAX_MAP_PLANES];
  52.  
  53. int WriteNodePlanes_r (node_t *node)
  54. {
  55.     plane_t        *plane;
  56.     dplane_t    *dplane;
  57.  
  58.     if (node->planenum == -1)
  59.         return 0;
  60.     if (planemapping[node->planenum] == -1)
  61.     {    /* a new plane */
  62.         planemapping[node->planenum] = numplanes;
  63.         
  64.         if (numplanes == MAX_MAP_PLANES)
  65.             Error ("numplanes == MAX_MAP_PLANES");
  66.         plane = &planes[node->planenum];
  67.         dplane = &dplanes[numplanes];
  68.         dplane->normal[0] = plane->normal[0];
  69.         dplane->normal[1] = plane->normal[1];
  70.         dplane->normal[2] = plane->normal[2];
  71.         dplane->dist = plane->dist;
  72.         dplane->type = plane->type;
  73.  
  74.         numplanes++;
  75.     }
  76.  
  77.     node->outputplanenum = planemapping[node->planenum];
  78.     
  79.     return 1 + WriteNodePlanes_r (node->children[0]) + WriteNodePlanes_r (node->children[1]);
  80. }
  81.  
  82. /*
  83. ==================
  84. WriteNodePlanes
  85.  
  86. ==================
  87. */
  88. int WriteNodePlanes (node_t *nodes)
  89. {
  90.     memset (planemapping,-1, sizeof(planemapping));
  91.     return(WriteNodePlanes_r (nodes));
  92. }
  93.  
  94. /*=========================================================================== */
  95.  
  96. /*
  97. ==================
  98. WriteClipNodes_r
  99.  
  100. ==================
  101. */
  102. int WriteClipNodes_r (node_t *node)
  103. {
  104.     int            i, c;
  105.     dclipnode_t    *cn;
  106.     int            num;
  107.     
  108. /* FIXME: free more stuff?     */
  109.     if (node->planenum == -1)
  110.     {
  111.         num = node->contents;
  112.         free (node);
  113.         return num;
  114.     }
  115.     
  116. /* emit a clipnode */
  117.     c = numclipnodes;
  118.     cn = &dclipnodes[numclipnodes];
  119.     numclipnodes++;
  120.     cn->planenum = node->outputplanenum;
  121.     for (i=0 ; i<2 ; i++)
  122.         cn->children[i] = WriteClipNodes_r(node->children[i]);
  123.     
  124.     free (node);
  125.     return c;
  126. }
  127.  
  128. /*
  129. ==================
  130. WriteClipNodes
  131.  
  132. Called after the clipping hull is completed.  Generates a disk format
  133. representation and frees the original memory.
  134. ==================
  135. */
  136. void WriteClipNodes (node_t *nodes)
  137. {
  138.     headclipnode = numclipnodes;
  139.     WriteClipNodes_r (nodes);
  140. }
  141.  
  142. /*=========================================================================== */
  143.  
  144. /*
  145. ==================
  146. WriteLeaf
  147. ==================
  148. */
  149. void WriteLeaf (node_t *node)
  150. {
  151.     face_t        **fp, *f;
  152.     dleaf_t        *leaf_p;
  153.         
  154. /* emit a leaf */
  155.     leaf_p = &dleafs[numleafs];
  156.     numleafs++;
  157.  
  158.     leaf_p->contents = node->contents;
  159.  
  160. /* */
  161. /* write bounding box info */
  162. /*     */
  163.     VectorCopy (node->mins, leaf_p->mins);
  164.     VectorCopy (node->maxs, leaf_p->maxs);
  165.     
  166.     leaf_p->visofs = -1;    /* no vis info yet */
  167.     
  168. /* */
  169. /* write the marksurfaces */
  170. /* */
  171.     leaf_p->firstmarksurface = nummarksurfaces;
  172.     
  173.     for (fp=node->markfaces ; *fp ; fp++)
  174.     {
  175.     /* emit a marksurface */
  176.         if (nummarksurfaces == MAX_MAP_MARKSURFACES)
  177.             Error ("nummarksurfaces == MAX_MAP_MARKSURFACES");
  178.         f = *fp;
  179.         do
  180.         {
  181.             dmarksurfaces[nummarksurfaces] =  f->outputnumber;
  182.             nummarksurfaces++;
  183.             f=f->original;        /* grab tjunction split faces */
  184.         } while (f);
  185.     }
  186.     
  187.     leaf_p->nummarksurfaces = nummarksurfaces - leaf_p->firstmarksurface;
  188. }
  189.  
  190.  
  191. /*
  192. ==================
  193. WriteDrawNodes_r
  194. ==================
  195. */
  196. void WriteDrawNodes_r (node_t *node)
  197. {
  198.     dnode_t    *n;
  199.     int        i;
  200.  
  201. /* emit a node     */
  202.     if (numnodes == MAX_MAP_NODES)
  203.         Error ("numnodes == MAX_MAP_NODES");
  204.     n = &dnodes[numnodes];
  205.     numnodes++;
  206.  
  207.     VectorCopy (node->mins, n->mins);
  208.     VectorCopy (node->maxs, n->maxs);
  209.  
  210.     n->planenum = node->outputplanenum;
  211.     n->firstface = node->firstface;
  212.     n->numfaces = node->numfaces;
  213.  
  214. /* */
  215. /* recursively output the other nodes */
  216. /*     */
  217.     
  218.     for (i=0 ; i<2 ; i++)
  219.     {
  220.         if (node->children[i]->planenum == -1)
  221.         {
  222.             if (node->children[i]->contents == CONTENTS_SOLID)
  223.                 n->children[i] = -1;
  224.             else
  225.             {
  226.                 n->children[i] = -(numleafs + 1);
  227.                 WriteLeaf (node->children[i]);
  228.             }
  229.         }
  230.         else
  231.         {
  232.             n->children[i] = numnodes;    
  233.             WriteDrawNodes_r (node->children[i]);
  234.         }
  235.     }
  236. }
  237.  
  238. /*
  239. ==================
  240. WriteDrawNodes
  241. ==================
  242. */
  243. void WriteDrawNodes (node_t *headnode)
  244. {
  245.     int        i;
  246.     int        start;
  247.     dmodel_t    *bm;
  248.  
  249. #if 0
  250.     if (headnode->contents < 0)
  251.         Error ("FinishBSPModel: empty model");
  252. #endif
  253.  
  254. /* emit a model */
  255.     if (nummodels == MAX_MAP_MODELS)
  256.         Error ("nummodels == MAX_MAP_MODELS");
  257.     bm = &dmodels[nummodels];
  258.     nummodels++;
  259.     
  260.     bm->headnode[0] = numnodes;
  261.     bm->firstface = firstface;
  262.     bm->numfaces = numfaces - firstface;    
  263.     firstface = numfaces;
  264.     
  265.     start = numleafs;
  266.  
  267.     if (headnode->contents < 0)    
  268.         WriteLeaf (headnode);
  269.     else
  270.         WriteDrawNodes_r (headnode);
  271.     bm->visleafs = numleafs - start;
  272.     
  273.     for (i=0 ; i<3 ; i++)
  274.     {
  275.         bm->mins[i] = headnode->mins[i] + SIDESPACE + 1;    /* remove the padding */
  276.         bm->maxs[i] = headnode->maxs[i] - SIDESPACE - 1;
  277.     }
  278. /* FIXME: are all the children decendant of padded nodes? */
  279. }
  280.  
  281.  
  282. /*
  283. ==================
  284. BumpModel
  285.  
  286. Used by the clipping hull processes that only need to store headclipnode
  287. ==================
  288. */
  289. void BumpModel (int hullnum)
  290. {
  291.     dmodel_t    *bm;
  292.  
  293. /* emit a model */
  294.     if (nummodels == MAX_MAP_MODELS)
  295.         Error ("nummodels == MAX_MAP_MODELS");
  296.     bm = &dmodels[nummodels];
  297.     nummodels++;
  298.     
  299.     bm->headnode[hullnum] = headclipnode;
  300. }
  301.  
  302. /*============================================================================= */
  303.  
  304. typedef struct
  305. {
  306.     char        identification[4];        /* should be WAD2 */
  307.     int            numlumps;
  308.     int            infotableofs;
  309. } wadinfo_t;
  310.  
  311.  
  312. typedef struct
  313. {
  314.     int            filepos;
  315.     int            disksize;
  316.     int            size;                    /* uncompressed */
  317.     char        type;
  318.     char        compression;
  319.     char        pad1, pad2;
  320.     char        name[16];                /* must be null terminated */
  321. } lumpinfo_t;
  322.  
  323. FILE        *texfile;
  324. wadinfo_t    wadinfo;
  325. lumpinfo_t    *lumpinfo;
  326.  
  327. void CleanupName (char *in, char *out)
  328. {
  329.     int        i;
  330.     
  331.     for (i=0 ; i< 16 ; i++ )
  332.     {
  333.         if (!in[i])
  334.             break;
  335.             
  336.         out[i] = toupper(in[i]);
  337.     }
  338.     
  339.     for ( ; i< 16 ; i++ )
  340.         out[i] = 0;
  341. }
  342.  
  343.  
  344. /*
  345. =================
  346. TEX_InitFromWad
  347. =================
  348. */
  349. void    TEX_InitFromWad (char *path)
  350. {
  351.     int            i;
  352.     
  353.     texfile = SafeOpenRead (path);
  354.     SafeRead (texfile, &wadinfo, sizeof(wadinfo));
  355.     if (strncmp (wadinfo.identification, "WAD2", 4))
  356.         Error ("TEX_InitFromWad: %s isn't a wadfile",path);
  357.     wadinfo.numlumps = LittleLong(wadinfo.numlumps);
  358.     wadinfo.infotableofs = LittleLong(wadinfo.infotableofs);
  359.     fseek (texfile, wadinfo.infotableofs, SEEK_SET);
  360.     lumpinfo = malloc(wadinfo.numlumps*sizeof(lumpinfo_t));
  361.     SafeRead (texfile, lumpinfo, wadinfo.numlumps*sizeof(lumpinfo_t));
  362.     
  363.     for (i=0 ; i<wadinfo.numlumps ; i++)
  364.     {
  365.         CleanupName (lumpinfo[i].name, lumpinfo[i].name);
  366.         lumpinfo[i].filepos = LittleLong(lumpinfo[i].filepos);
  367.         lumpinfo[i].disksize = LittleLong(lumpinfo[i].disksize);
  368.     }
  369. }
  370.  
  371. /*
  372. ==================
  373. LoadLump
  374. ==================
  375. */
  376. int LoadLump (char *name, byte *dest)
  377. {
  378.     int        i;
  379.     char    cname[16];
  380.     
  381.     CleanupName (name, cname);
  382.     
  383.     for (i=0 ; i<wadinfo.numlumps ; i++)
  384.     {
  385.         if (!strcmp(cname, lumpinfo[i].name))
  386.         {
  387.             fseek (texfile, lumpinfo[i].filepos, SEEK_SET);
  388.             SafeRead (texfile, dest, lumpinfo[i].disksize);
  389.             return lumpinfo[i].disksize;
  390.         }
  391.     }
  392.     
  393.     ShowWarningEntry("Texture %s not found", name);
  394.     sleep(1);
  395.         return 0;
  396. }
  397.  
  398.  
  399. /*
  400. ==================
  401. AddAnimatingTextures
  402. ==================
  403. */
  404. void AddAnimatingTextures (void)
  405. {
  406.     int        base;
  407.     int        i, j, k;
  408.     char    name[32];
  409.  
  410.     base = nummiptex;
  411.     
  412.     for (i=0 ; i<base ; i++)
  413.     {
  414.         if (miptex[i][0] != '+')
  415.             continue;
  416.         strcpy (name, miptex[i]);
  417.  
  418.         for (j=0 ; j<20 ; j++)
  419.         {
  420.             if (j < 10)
  421.                 name[1] = '0'+j;
  422.             else
  423.                 name[1] = 'A'+j-10;        /* alternate animation */
  424.             
  425.  
  426.         /* see if this name exists in the wadfile */
  427.             for (k=0 ; k<wadinfo.numlumps ; k++)
  428.                 if (!strcmp(name, lumpinfo[k].name))
  429.                 {
  430.                     FindMiptex (name);    /* add to the miptex list */
  431.                     break;
  432.                 }
  433.         }
  434.     }
  435.     
  436.     ShowTempEntry("Added %i texture frames.", nummiptex - base);
  437. }
  438.  
  439. /*
  440. ==================
  441. WriteMiptex
  442. ==================
  443. */
  444. void WriteMiptex (void)
  445. {
  446.     int        i, len;
  447.     byte    *data;
  448.     dmiptexlump_t    *l;
  449.     char    *path;
  450.     char    fullpath[1024];
  451.  
  452.     path = ValueForKey (&entities[0], "wad");
  453.     sprintf (fullpath, "%s%s", projectpath, path);
  454.  
  455.     TEX_InitFromWad (fullpath);
  456.     
  457.     AddAnimatingTextures ();
  458.  
  459.     l = (dmiptexlump_t *)dtexdata;
  460.     data = (byte *)&l->dataofs[nummiptex];
  461.     l->nummiptex = nummiptex;
  462.     for (i=0 ; i<nummiptex ; i++)
  463.     {
  464.         l->dataofs[i] = data - (byte *)l;
  465.         len = LoadLump (miptex[i], data);
  466.         if (data + len - dtexdata >= MAX_MAP_MIPTEX)
  467.             Error ("Textures exceeded MAX_MAP_MIPTEX");
  468.         if (!len)
  469.             l->dataofs[i] = -1;    /* didn't find the texture */
  470.         data += len;
  471.     }
  472.  
  473.     texdatasize = data - dtexdata;
  474. }
  475.  
  476. /*=========================================================================== */
  477.  
  478.  
  479. /*
  480. ==================
  481. BeginBSPFile
  482. ==================
  483. */
  484. void BeginBSPFile (void)
  485. {
  486. /* edge 0 is not used, because 0 can't be negated */
  487.     numedges = 1;
  488.  
  489. /* leaf 0 is common solid with no faces */
  490.     numleafs = 1;
  491.     dleafs[0].contents = CONTENTS_SOLID;
  492.  
  493.     firstface = 0;    
  494. }
  495.  
  496.  
  497. /*
  498. ==================
  499. FinishBSPFile
  500. ==================
  501. */
  502. void FinishBSPFile (void)
  503. {
  504.     ShowStatusEntry ("BSP data creation complete.");
  505.  
  506.         ShowTempEntry("Writing BSP file: %s\n", bspfilename);
  507.     WriteMiptex ();
  508.  
  509.     PrintBSPFileSizes ();
  510.     WriteBSPFile (bspfilename);
  511. }
  512.  
  513.